package br.com.intelsys.security.ldap;

import java.util.List;

import javax.naming.NamingException;
import javax.naming.directory.Attributes;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.ldap.core.AttributesMapper;
import org.springframework.ldap.core.DistinguishedName;
import org.springframework.ldap.core.LdapTemplate;

public class LdapQuery {
	private final LdapTemplate ldapTemplate;
	private String host;
	private int port;
	private boolean v3;
	private boolean tls;
	private boolean followRef;
	private boolean bindAndSearch;
	private String baseDn;
	private String searchString;
	private String userDn;
	private String connUser;
	private String connPass;

	protected static final Log log = LogFactory.getLog(LdapQuery.class);

	public LdapQuery(LdapTemplate ldapTemplate) {
		this.ldapTemplate = ldapTemplate;
	}

	public LdapObject authenticate(String login, String pass) {
		String filterStr = searchString.replaceFirst("\\?", login);
		if (ldapTemplate.authenticate(DistinguishedName.EMPTY_PATH, "(" + filterStr + ")", pass)) {
			List<Attributes> attrList = ldapTemplate.search("", filterStr, new AttributesMapper() {
				public Object mapFromAttributes(Attributes attrs) throws NamingException, javax.naming.NamingException {
					return attrs;
				}
			});
			if (log.isDebugEnabled()) {
				for (Attributes attrs : attrList) {
					log.debug(attrs);
				}
			}
			for (Attributes attrs : attrList) {
				return new LdapObject(attrs);
			}
		}
		return null;
	}

	public LdapQuery host(String host) {
		this.host = host;
		return this;
	}

	public LdapQuery port(int port) {
		this.port = port;
		return this;
	}

	public LdapQuery version3(boolean version3) {
		this.v3 = version3;
		return this;
	}

	public LdapQuery tls(boolean negotiateTls) {
		this.tls = tls;
		return this;
	}

	public LdapQuery followRef(boolean followRef) {
		this.followRef = followRef;
		return this;
	}

	public LdapQuery bindAndSearch(boolean bindAndSearch) {
		this.bindAndSearch = bindAndSearch;
		return this;
	}

	public LdapQuery baseDn(String baseDn) {
		this.baseDn = baseDn;
		return this;
	}

	public LdapQuery searchString(String searchString) {
		this.searchString = searchString;
		return this;
	}

	public LdapQuery userDn(String userDn) {
		this.userDn = userDn;
		return this;
	}

	public LdapQuery connUser(String user) {
		this.connUser = user;
		return this;
	}

	public LdapQuery connPass(String pass) {
		this.connPass = pass;
		return this;
	}
}
